import { error, warn ,js} from "cc";
import { StringUtil } from "../../core/utils/StringUtil";

export enum HttpRequestMethods{
    GET="GET",
    POST="POST",
    UPDATE="UPDATE",
    DELETE="DELETE",
    OPTIONS="OPTIONS"
}

export enum HttpResponseType{
    JSON="json",
    ARRAYBUFFER="arraybuffer",
    BLOB="blob",
    DOCUMENT="document"
}
/**
 * 接口返回的数据格式
 */
export class HttpResponseCallback{
    /**是否请求成功 */
    isSuccess:boolean=false;
    /**请求返回数据 */
    res?:any;
    /**接口返回的错误数据 */
    err?:any;
}

export enum HttpCallbackEvent{
    /**断网 */
    NO_NETWORK="http_reqeust_no_network",
    /**未知错误 */
    UNKNOWN_ERROR="http_reqeust_unknown_error",
    /**请求超时 */
    TIMEOUT="http_reqeust_timeout"
}

/**
 * 请求返回数据格式
 */
type HttpCallback = (ret:HttpResponseCallback)=>void

/**
 * 请求接口集合
 */
var urls:any={}
/**
 * 请求接口参数
 */
var requestParam:any={}

export class HttpRequest{
    server:string = "";
    timeout:number = 10000;
    //请求头信息
    private header:Map<string,string> = new Map<string,string>();
    //添加请求头信息
    public addHeader(headerName:string,value:string):void{
        this.header.set(headerName,value)
    }

  
    public get(url:string,onCompleted:HttpCallback):void;
    public get(url:string,oncompleted:HttpCallback,onErrorCallback:HttpCallback):void;
    public get(url:string,oncompleted:HttpCallback,responseType:HttpResponseType)
    public get(url:string,onCompleted:HttpCallback,onErrorCallback?:HttpCallback,responseType?:HttpResponseType):void;
  
   
    public get(url:string,params:any,onCompleted:HttpCallback):void;
    public get(url:string,params:any,onCompleted:HttpCallback,onErrorCallback:HttpCallback):void;
    public get(url:string,params:any,oncompleted:HttpCallback,responseType:HttpResponseType):void;
    public get(url:string,params:any,onCompleted:HttpCallback,onErrorCallback:HttpCallback,responseType:HttpResponseType):void;

    public get(
        url:string,
        params?:any | HttpCallback,
        onCompleted?:HttpCallback|HttpResponseType,
        onErrorCallback?:HttpCallback|HttpResponseType,
        responseType?:HttpResponseType
        ){

            let newParam:any;
            let newCompleted:any;
            let newErrorCallback:any;
            if ( typeof params === "function") { 
                newCompleted = params as HttpCallback;
                newParam  = undefined
                if( typeof onCompleted ==="string"){
                    responseType = onCompleted as HttpResponseType;
                    newErrorCallback = undefined;
                }else{
                    newErrorCallback = onCompleted as HttpCallback;
                } 
                
                if (typeof onErrorCallback === "string") {
                    responseType = onErrorCallback as HttpResponseType;
                }

            }else{
               newParam = params;
               newCompleted = onCompleted;
               if (typeof onErrorCallback === "string") {
                responseType = onErrorCallback as HttpResponseType
                newErrorCallback = undefined
               }else{
                newErrorCallback = onErrorCallback
               }

            }


            this.sendReqeust(url,HttpRequestMethods.GET,newParam,newCompleted,newErrorCallback,responseType);

        
    }

   



    protected sendReqeust(
        url:string,
        method?:HttpRequestMethods, 
        params?:any,
        onCompleted?:HttpCallback,
        onErrorCallback?:HttpCallback,
        responseType?:HttpResponseType){
            if (StringUtil.isEmpty(url)) {
                error("请求地址不能为空");
                return;
            }
            if (urls[url] != null) {
                warn("接口已经在请求中，请勿重复请求");
                return;
            }
            var xhr = new XMLHttpRequest();
            xhr.timeout = this.timeout;
            //设置请求头
            for (const [k,v] of this.header) {
                xhr.setRequestHeader(k,v);
            }
            if (url.toLocaleLowerCase().indexOf("http") != 0) {
                url  = this.server+url
            }
            // 将请求添加到请求队列中来。防止重复请求
            urls[url] = xhr;
            let ret:HttpResponseCallback = new HttpResponseCallback();
            xhr.onload = ()=>{
                console.log(xhr.status)
                if (xhr.status == 500) {
                //服务器错误 
                    ret.isSuccess = false;
                    ret.err = HttpCallbackEvent.NO_NETWORK;//网络连接已断开
                    this.delteCache(url);
                    onErrorCallback && onErrorCallback(ret);
                }
            }
            xhr.onerror=()=>{
                // console.log(11111)
                this.delteCache(url);
                ret.isSuccess = false;
                if (xhr.readyState == 0 || xhr.readyState == 1 || xhr.status == 0) {
                    ret.err = HttpCallbackEvent.NO_NETWORK;//网络断开
                }else{
                    ret.err = HttpCallbackEvent.UNKNOWN_ERROR;//未知错误
                }
                onErrorCallback && onErrorCallback(ret);
            }
      
            xhr.onreadystatechange = ()=>{
                this.delteCache(url);
                if (xhr.readyState!=4) {
                    return;
                }
                if (xhr.status >= 200&&xhr.status < 400) {
                    ret.isSuccess = true;
                  switch (responseType) {
                    case HttpResponseType.ARRAYBUFFER:
                    case HttpResponseType.BLOB:
                    case HttpResponseType.DOCUMENT:
                        ret.res = xhr.response
                        break;
                    case HttpResponseType.JSON:
                        ret.res = JSON.parse(xhr.response)
                        break;
                    default:
                        ret.res = JSON.parse(xhr.response)
                        break;
                  }

                    onCompleted && onCompleted(ret);
                }else{
                    // console.log(222)
                    ret.isSuccess = false;
                    ret.err = HttpCallbackEvent.NO_NETWORK;
                    onErrorCallback && onErrorCallback(ret);
                }
            }

            xhr.open(method!,url);

            if (method==HttpRequestMethods.POST) {
              
                if (params!=null) {
                    xhr.send(params);
                }else{
                   xhr.send(); 
                }

            } else{
                if (params!=null) {
                    let parma = this.formatParams(params);
                    xhr.send(this.formatParams(params));
                }else{
                    xhr.send();
                }
                
            }
    }


    private formatParams(params:any){

        Object.keys(params).forEach((key:any)=>{
            console.log(key,params[key])
        })

        var result = "";
        for (var name in params) {
            let data = params[name];
            if (data instanceof Object) {
                for (var key in data)
                    result += `${key}=${data[key]}&`;
            }
            else {
                result += `${name}=${data}&`;
            }
        }
        return result.substring(0, result.length - 1);
    }
    

    public requestAsync(url:string,):Promise<HttpCallback>{
        return new Promise<HttpCallback>((resolve,reject)=>{

        })
    }

    private delteCache(url:string){
        delete urls[url];
    }
}

